#define _POSIX_SOURCE
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include "liblog.h"

void _imprimir_encabezado (); 

void loguear_evento (const char *evento, const char *proc, pthread_t pthread, const char *thread, const char *tipo) {

FILE *archevento;
time_t t;
time(&t);
char *pid = (char*) reservar(20);
sprintf(pid,"%i",getpid());
char *nthread = (char*) reservar (20);
sprintf(nthread,"%lu",pthread);

archevento=fopen("./archevento.log","a");
	if (!archevento){
		perror("Error al intentar abrir el archivo");
	}

fputs(ctime (&t),archevento);
fputs(" ",archevento);
fputs("[",archevento);
fputs(proc,archevento);
fputs("/",archevento);
fputs(pid,archevento);
fputs("] ",archevento);
fputs("[",archevento);
fputs(nthread,archevento);
fputs("/",archevento);
fputs(thread,archevento);
fputs("] ",archevento);
fputs("[",archevento);
fputs(tipo,archevento);
fputs("] : ",archevento);
fputs(evento,archevento);
fputs("\n",archevento);	
fclose(archevento);
liberar(pid);
liberar(nthread);

}

void loguear_change_list (int id, int lista1, int lista2, Tabla *tablaProcesos, const char *proc, pthread_t pthread, const char *thread, const char *tipo) {

FILE *archestados;
FILE *estadoproceso;
time_t t;
time(&t);
char *pid = (char*) reservar(20);
sprintf(pid,"%i",getpid());
char *nthread = (char*) reservar (20);
sprintf(nthread,"%lu",pthread);

char *path = (char*)reservar(MAXPATH);
char *nombre;
char *viene = (char*)reservar(50);
char *va = (char*)reservar(50);


nombre = getFileName(getName(tablaProcesos,id));
sprintf(path,"./estado_%s.log",nombre);

archestados=fopen("./archestados.log","a");
	if (!archestados){
		perror("Error al intentar abrir el archivo");
	}
estadoproceso=fopen(path,"a");
	if (!estadoproceso){
		perror("Error al intentar abrir el archivo");
	}

switch (lista1) {
	case ENTRADA: strcpy(viene,"ENTRADA");
			break;
	case NUEVO: strcpy(viene,"NUEVOS");
			break;
	case LISTO: strcpy(viene,"LISTOS");
			break;
	case BLOQ: strcpy(viene,"BLOQUEADOS");
			break;
	case IOTERM: strcpy(viene,"IO TERMINADA");
			break;
	case SUSPLISTO: strcpy(viene,"SUSPENDIDOS/LISTOS");
			break;
	case EXSUSP: strcpy(viene,"EX-SUSPENDIDOS");
			break;
}

switch (lista2) {
	case ENTRADA: strcpy(va,"ENTRADA");
			break;
	case NUEVO: strcpy(va,"NUEVOS");
			break;
	case LISTO: strcpy(va,"LISTOS");
			break;
	case BLOQ: strcpy(va,"BLOQUEADOS");
			break;
	case IOTERM: strcpy(va,"IO TERMINADA");
			break;
	case SUSPLISTO: strcpy(va,"SUSPENDIDOS/LISTOS");
			break;
	case EXSUSP: strcpy(va,"EX-SUSPENDIDOS");
			break;
}

fputs(ctime (&t),archestados);
fputs(" ",archestados);
fputs("[",archestados);
fputs(proc,archestados);
fputs("/",archestados);
fputs(pid,archestados);
fputs("] ",archestados);
fputs("[",archestados);
fputs(thread,archestados);
fputs("/",archestados);
fputs(nthread,archestados);
fputs("] ",archestados);
fputs("[",archestados);
fputs(tipo,archestados);
fputs("] : ",archestados);
fputs("\n",archestados);	
fputs("Nombre del proceso: ",archestados);
fputs(nombre,archestados);
fputs("\n",archestados);
fputs("Lista de la que proviene: ",archestados);
fputs(viene,archestados);
fputs("\n",archestados);
fputs("Lista a la cual va: ",archestados);
fputs(va,archestados);
fputs("\n",archestados);
fputs("------------------------------------------------------",archestados);
fputs("\n",archestados);

fputs(ctime (&t),estadoproceso);
fputs(" ",estadoproceso);
fputs("[",estadoproceso);
fputs(proc,estadoproceso);
fputs("/",estadoproceso);
fputs(pid,estadoproceso);
fputs("] ",estadoproceso);
fputs("[",estadoproceso);
fputs(thread,estadoproceso);
fputs("/",estadoproceso);
fputs(nthread,estadoproceso);
fputs("] ",estadoproceso);
fputs("[",estadoproceso);
fputs(tipo,estadoproceso);
fputs("] : ",estadoproceso);
fputs("\n",estadoproceso);	
fputs("Nombre del proceso: ",estadoproceso);
fputs(nombre,estadoproceso);
fputs("\n",estadoproceso);
fputs("Lista de la que proviene: ",estadoproceso);
fputs(viene,estadoproceso);
fputs("\n",estadoproceso);
fputs("Lista a la cual va: ",estadoproceso);
fputs(va,estadoproceso);
fputs("\n",estadoproceso);
fputs("--------------------------------------------------------",estadoproceso);
fputs("\n",estadoproceso);

liberar(path);
liberar(viene);
liberar(va);
liberar(nthread);
liberar(pid);
fclose(estadoproceso);
fclose(archestados);

}

void loguearPCP (Lista *listalistos,Lista *listaExSuspendidos,Lista *listaSuspendidosListos, Tabla *tabla, const char *tipo) {

FILE *system_state;
int i;
char *name = (char*)reservar(15);
int elemlistos, elemExSuspendidos, elemSuspendidosListos;
int pid;
char *id = (char*) reservar(20);
sprintf(id,"%i",getpid());

system_state=fopen("./system_state.log","a");
	if (!system_state){
		perror("Error al intentar abrir el archivo");
	}

fputs(" ",system_state);
fputs("[",system_state);
fputs("PCP",system_state);
fputs("/",system_state);
fputs(id,system_state);
fputs("] ",system_state);
fputs("[",system_state);
fputs(tipo, system_state);
fputs("] : ",system_state);
fputs("\n",system_state);	

_imprimir_encabezado();

lockLista(listalistos);
fputs("Listos: ",system_state);
elemlistos = cantidadElementos (listalistos); 

if (elemlistos==0) {
	fputs("<ninguno>",system_state);}
else {
	for(i = 0; i < elemlistos; i++) {
		pid = elementoEnPosicion(listalistos, i);
		strcpy(name,getFileName(getName (tabla, pid)));
		fputs(name,system_state);
		fputs("<---",system_state);
	}
}

unlockLista(listalistos);
fputs("\n",system_state);
lockLista(listaExSuspendidos);
fputs("ExSuspendidos: ",system_state);
elemExSuspendidos = cantidadElementos (listaExSuspendidos);

if (elemExSuspendidos==0) {
	fputs("<ninguno>",system_state);}
else {
	for(i = 0; i < elemExSuspendidos; i++) {
		pid = elementoEnPosicion (listaExSuspendidos, i);
		strcpy(name,getFileName(getName (tabla, pid)));
		fputs(name,system_state);
		fputs("<---",system_state);
	}
}

unlockLista(listaExSuspendidos);
fputs("\n",system_state);
lockLista(listaSuspendidosListos);
fputs("SuspendidosListos: ",system_state);
elemSuspendidosListos = cantidadElementos (listaSuspendidosListos);

if (elemSuspendidosListos==0) {
	fputs("<ninguno>",system_state);}
else {
	for(i = 0; i < elemSuspendidosListos; i++) {
		pid = elementoEnPosicion (listaSuspendidosListos, i);
		strcpy(name,getFileName(getName (tabla, pid)));
		fputs(name,system_state);
		fputs("<---",system_state);
	}
}

fputs("\n",system_state);
fputs("\n",system_state);
unlockLista(listaSuspendidosListos);
liberar(name);
liberar(id);
fclose(system_state);

}

void loguearMLP (Lista *listaNuevos,Lista *listaBloqueados,Lista *listaIOTerminada, Tabla *tabla, const char *tipo) {

FILE *system_state;
char *name = (char*)reservar(50);
int i;
int elemNuevos, elemBloqueados, elemIO;
int pid;
char *id = (char*) reservar(20);
sprintf(id,"%i",getpid());

system_state=fopen("./system_state.log","a");
	if (!system_state){
		perror("Error al intentar abrir el archivo");
	}
	
fputs(" ",system_state);
fputs("[",system_state);
fputs("MLP",system_state);
fputs("/",system_state);
fputs(id,system_state);
fputs("] ",system_state);
fputs("[",system_state);
fputs(tipo,system_state);
fputs("] : ",system_state);
fputs("\n",system_state);

_imprimir_encabezado();


lockLista(listaNuevos);
fputs("Nuevos: ",system_state);
elemNuevos = cantidadElementos (listaNuevos);

if (elemNuevos==0) {
	fputs("<ninguno>",system_state);}
else {
	for(i = 0; i < elemNuevos; i++) {
		pid = elementoEnPosicion (listaNuevos, i);
		strcpy(name,getFileName(getName (tabla, pid)));
		fputs(name,system_state);
		fputs("<---",system_state);
	}
}

unlockLista(listaNuevos);
fputs("\n",system_state);
lockLista(listaBloqueados);
fputs("Bloqueados: ",system_state);
elemBloqueados = cantidadElementos (listaBloqueados);

if (elemBloqueados==0) {
	fputs("<ninguno>",system_state);}
else {
	for(i = 0; i < elemBloqueados; i++) {
		pid = elementoEnPosicion (listaBloqueados, i); 
		strcpy(name,getFileName(getName (tabla, pid)));
		fputs(name,system_state);
		fputs("<---",system_state);
	}
}

unlockLista(listaBloqueados);
fputs("\n",system_state);
lockLista(listaIOTerminada);
fputs("IOTerminada: ",system_state);
elemIO = cantidadElementos (listaIOTerminada);

if (elemIO==0) {
	fputs("<ninguno>",system_state);}
else {
	for(i = 0; i < elemIO; i++) {
		pid = elementoEnPosicion (listaIOTerminada, i);
		strcpy(name,getFileName(getName (tabla, pid)));
		fputs(name,system_state);
		fputs("<---",system_state);
	}
}
fputs("\n",system_state);
fputs("\n",system_state);
unlockLista(listaIOTerminada);
liberar(name);
liberar(id);
fclose(system_state);

}

void loguear_program_finish (int id, Tabla *tablaProcesos, const char *proc, pthread_t pthread, const char *thread, const char *tipo) {

Proceso * p = getProceso(tablaProcesos,id);
FILE *finPrograma;
char *nombre;
char *path = (char*) reservar (MAXPATH);
nombre = getFileName(getName(tablaProcesos,id));
sprintf(path,"./fin_%s.log",nombre);
time_t t;
time(&t);
char *pid = (char*) reservar(20);
sprintf(pid,"%i",getpid());
char *nthread = (char*) reservar (20);
sprintf(nthread,"%lu",(unsigned long int)pthread);

finPrograma = fopen(path,"a");
	if (!finPrograma){
		perror("Error al intentar abrir el archivo");
	}

fputs("----------------------------------------------------------------", finPrograma);
fputs("\n",finPrograma);
fputs(ctime (&t),finPrograma);
fputs(" ",finPrograma);
fputs("[",finPrograma);
fputs(proc,finPrograma);
fputs("/",finPrograma);
fputs(pid,finPrograma);
fputs("] ",finPrograma);
fputs("[",finPrograma);
fputs(thread,finPrograma);
fputs("/",finPrograma);
fputs(nthread,finPrograma);
fputs("] ",finPrograma);
fputs("[",finPrograma);
fputs(tipo,finPrograma);
fputs("] : ",finPrograma);
fputs("Programa: ",finPrograma);
fputs(nombre,finPrograma);
fputs("\n",finPrograma);

printf("\nPrograma finalizado: %s \n",nombre);
imprimirVariablesOut(p);
imprimirVariables(p, finPrograma);
fputs("\n----------------------------------------------------------------",finPrograma);

liberar(path);
liberar(pid);
liberar(nthread);
fclose(finPrograma);
}

void _imprimir_encabezado () {

FILE *system_state;
time_t t;
time (&t);

system_state=fopen("./system_state.log","a");
	if (!system_state){
		perror("Error al intentar abrir el archivo");
	}

fputs("-----------------------------------------------------------------\n",system_state);
fputs("ESTADO DEL SISTEMA A LAS ",system_state);
fputs(ctime (&t),system_state);
fputs("\n",system_state);
fputs("------------------------------------------------------------------\n",system_state);

fclose(system_state);

}
